/**
 * 
 */
package idv.takeshi.software.productline.bookstore.application.service.dto;

import idv.takeshi.software.productline.bookstore.domain.model.useraccount.Sex;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccount;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccountFactory;

import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * A data-transfer Object for UserAccount model.
 * @author takeshi
 *
 */
public abstract class UserAccountDto <T extends UserAccount> {
	
	
	private Long id;
	
	@Pattern(regexp = ".+")
	@NotNull
	private String accountName;
	
	@Pattern(regexp = ".{5,}+")
	@NotNull
	private String password;
	
	@Pattern(regexp = ".{5,}+")
	@NotNull
	private String confirmedPassword;
	
	@Pattern(regexp = ".*")
	private String newPassword;
	
	@Pattern(regexp = ".*")
	private String confirmedNewPassword;
	
	
	@Pattern(regexp = ".+")
	@NotNull
	private String zipCode;
	
	@Pattern(regexp = ".+")
	@NotNull
	private String contactAddress;
	
	@Pattern(regexp = "\\d*")
	private String contactPhoneNumber;
	
	@Pattern(regexp = "\\d+")
	@NotNull
	private String cellPhoneNumber;
	
	@Pattern(regexp = ".+@.+\\.[a-z]+")
	@NotNull
	private String emailAddress;

	/**
	 *Default Constructor. 
	 */
	public UserAccountDto() {
		super();
	}
	
	/**
	 * Initial this dto by given user account model.
	 */
	public UserAccountDto(UserAccount userAccount){
		Validate.notNull(userAccount, "userAccount shall always not be null");
		
		this.setId(userAccount.getId());
		this.setAccountName(userAccount.getAccountName());
		this.setZipCode(userAccount.getZipCode());
		this.setContactAddress(userAccount.getContactAddress());
		this.setContactPhoneNumber(userAccount.getContactPhoneNumber());
		this.setCellPhoneNumber(userAccount.getCellPhoneNumber());
		this.setEmailAddress(userAccount.getEmailAddress());
	}

	/**
	 * @return the accountName
	 */
	public String getAccountName() {
		return accountName;
	}

	/**
	 * @param accountName the accountName to set
	 */
	public void setAccountName(String accountName) {
		this.accountName = accountName;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the confirmedPassword
	 */
	public String getConfirmedPassword() {
		return confirmedPassword;
	}

	/**
	 * @param confirmedPassword the confirmedPassword to set
	 */
	public void setConfirmedPassword(String confirmedPassword) {
		this.confirmedPassword = confirmedPassword;
	}

	/**
	 * @return the zipCode
	 */
	public String getZipCode() {
		return zipCode;
	}

	/**
	 * @param zipCode the zipCode to set
	 */
	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	/**
	 * @return the contactAddress
	 */
	public String getContactAddress() {
		return contactAddress;
	}

	/**
	 * @param contactAddress the contactAddress to set
	 */
	public void setContactAddress(String contactAddress) {
		this.contactAddress = contactAddress;
	}

	/**
	 * @return the contactPhoneNumber
	 */
	public String getContactPhoneNumber() {
		return contactPhoneNumber;
	}

	/**
	 * @param contactPhoneNumber the contactPhoneNumber to set
	 */
	public void setContactPhoneNumber(String contactPhoneNumber) {
		this.contactPhoneNumber = contactPhoneNumber;
	}

	/**
	 * @return the cellPhoneNumber
	 */
	public String getCellPhoneNumber() {
		return cellPhoneNumber;
	}

	/**
	 * @param cellPhoneNumber the cellPhoneNumber to set
	 */
	public void setCellPhoneNumber(String cellPhoneNumber) {
		this.cellPhoneNumber = cellPhoneNumber;
	}

	/**
	 * @return the emailAddress
	 */
	public String getEmailAddress() {
		return emailAddress;
	}
	
	/**
	 * Get Model instance.
	 * @param userAccountFactory
	 * @return
	 */
	public abstract T createModel(UserAccountFactory userAccountFactory);
	
	
	/**
	 * Load property values into given user account model.
	 * @param userAccount
	 */
	public void loadModel(T userAccount){
		Validate.notNull(userAccount, "userAccount shall always not be null");
		userAccount.setAccountName(this.getAccountName());
		
		if(StringUtils.isNotBlank(this.getNewPassword()))
			userAccount.setOriginalPassword(this.getNewPassword());
		
		userAccount.setZipCode(this.getZipCode());
		userAccount.setContactAddress(this.getContactAddress());
		userAccount.setContactPhoneNumber(this.getContactPhoneNumber());
		userAccount.setCellPhoneNumber(this.getCellPhoneNumber());
		userAccount.setEmailAddress(this.getEmailAddress());
	}
	
	/**
	 * @param emailAddress the emailAddress to set
	 */
	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}


	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the newPassword
	 */
	public String getNewPassword() {
		return newPassword;
	}

	/**
	 * @param newPassword the newPassword to set
	 */
	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	/**
	 * @return the confirmedNewPassword
	 */
	public String getConfirmedNewPassword() {
		return confirmedNewPassword;
	}

	/**
	 * @param confirmedNewPassword the confirmedNewPassword to set
	 */
	public void setConfirmedNewPassword(String confirmedNewPassword) {
		this.confirmedNewPassword = confirmedNewPassword;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
	}
	

}
